/*
 * CS_ULTIMATE_EVOLUTION_FAIRY.cpp
 *
 *  Created on: 2014. 2. 19.
 *      Author: mega
 */

#include "../../User.h"
#include "../../Command.h"
#include "../../NLogic/Bag.h"
#include "../../NLogic/Item.h"
#include "../../NResource/Static.h"

namespace ProjectZ { namespace NCommand {

static void SendResponse(User * pUser, int ack)
{
	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
	*pAck << static_cast<int16_t>(ack);
	pAck->MakePacket(CMD_SC_ULTIMATE_EVOLUTION_FAIRY);
	pUser->Send(pAck);
}

void Command::CS_ULTIMATE_EVOLUTION_FAIRY(User * pUser, ::Network::Packet * pPacket)
{
/*	CS_ULTIMATE_EVOLUTION_FAIRY      0x150a
	{
	           u64 u64fairy_seq;                                //진화 페어리 seq
	           u64 u64material_1;                              //재료 1 아이템
	           u8        u8material_1_count;                  //재료 1 갯수
	           u64 u64material_2;                              //재료 2 아이템
	           u8        u8material_2_count;                  //재료 2 갯수
	}
	SC_ULTIMATE_EVOLUTION_ FAIRY     0x150b
	{
	           s16       u16ack;
	}*/

	PREPARE_PACKET;

	uint64_t	fairySeq;
	uint64_t	itemSeq1;
	uint64_t	itemSeq2;
	uint8_t		itemQuantity1;
	uint8_t		itemQuantity2;

	*pPacket >> fairySeq >> itemSeq1 >> itemQuantity1 >> itemSeq2 >> itemQuantity2;

	NLogic::Bag * pBag = pUser->GetBag(BAG_TYPE_FAIRY);
	if (NULL == pBag)
	{
		DEBUGLOG("%s : pBag is NULL", __FUNCTION__);
		SendResponse(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	NLogic::Item * pFairy = pBag->GetItem(fairySeq);
	if (NULL == pFairy)
	{
		DEBUGLOG("%s : pFairy is NULL", __FUNCTION__);
		SendResponse(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	// 페어리 궁극진화는 MAX OPEN 등급 이하만 가능
	if (pFairy->GetData().quality >= MAX_OPEN_FAIRY_QUALITY)
	{
		SendResponse(pUser, ACK_FAIRY_GRADE_MISMATCH);
		return;
	}


	NLogic::Bag * pBagMisc = pUser->GetBag(BAG_TYPE_MISC);
	if (NULL == pBagMisc)
	{
		DEBUGLOG("%s : pBagMisc is NULL", __FUNCTION__);
		SendResponse(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	NLogic::Item * pItem1 = pBagMisc->GetItem(itemSeq1);
	if (NULL == pItem1)
	{
		DEBUGLOG("%s : pItem1 is NULL", __FUNCTION__);
		SendResponse(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	NLogic::Item * pItem2 = pBagMisc->GetItem(itemSeq2);
	if (NULL == pItem2)
	{
		DEBUGLOG("%s : pItem2 is NULL", __FUNCTION__);
		SendResponse(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	NResource::UltimateEvolutionResource::Key	clsKey;
	clsKey.evType	= static_cast<int>(NResource::UltimateEvolutionResource::EvolutionType::EM_ULTIMATE_FAIRY);
	clsKey.elType	= pFairy->GetData().eff_type[0];
	clsKey.level	= (pFairy->GetData().level >= 10) ? (pFairy->GetData().level / 10) * 10 : 1;

	NResource::UltimateEvolutionResource::Flyweight * pFly = NResource::Static::InstancePtr()->GetUltimateResource()->GetFly(clsKey);
	if (NULL == pFly)
	{
		DEBUGLOG("%s : pFly is NULL", __FUNCTION__);
		SendResponse(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	// 페어리 궁극진화에 맞는 재료 아이템인지 확인
	if (pItem1->GetData().sub_type != static_cast<int>(CLASS_ITEM_TABLE_ETC))
	{
		DEBUGLOG("%s : INVALID ITEM 1 SHEET = %d", __FUNCTION__, pItem1->GetData().sub_type);
		SendResponse(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	if (pItem2->GetData().sub_type != static_cast<int>(CLASS_ITEM_TABLE_ETC))
	{
		DEBUGLOG("%s : INVALID ITEM 2 SHEET = %d", __FUNCTION__, pItem1->GetData().sub_type);
		SendResponse(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	// 재료의 TID 확인
	if (pFly->_ITEM1_TID != pItem1->GetData().tid)
	{
		DEBUGLOG("%s : INVALID ITEM 1 TID = %d", __FUNCTION__, pItem1->GetData().tid);
		SendResponse(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	if (pFly->_ITEM2_TID != pItem2->GetData().tid)
	{
		DEBUGLOG("%s : INVALID ITEM 2 TID = %d", __FUNCTION__, pItem2->GetData().tid);
		SendResponse(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	// 재료의 갯수 확인
	if (pFly->_ITEM1_QUANTITY != itemQuantity1)
	{
		DEBUGLOG("%s : INVALID ITEM 1 QUANTITY=%d", __FUNCTION__, itemQuantity1);
		SendResponse(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	if (pFly->_ITEM2_QUANTITY != itemQuantity2)
	{
		DEBUGLOG("%s : INVALID ITEM 2 QUANTITY=%d", __FUNCTION__, itemQuantity2);
		SendResponse(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	// 재료의 부족 여부 확인
	if (0 > (pItem1->GetData().quantity - itemQuantity1) )
	{
		SendResponse(pUser, ACK_FAIRY_MATERIAL_LACK);
		return;
	}

	if (0 > (pItem2->GetData().quantity - itemQuantity2) )
	{
		SendResponse(pUser, ACK_FAIRY_MATERIAL_LACK);
		return;
	}

	// 페어리 궁극 진화
	int ack = NResource::Static::InstancePtr()->GetFairyGachya()->FairyUltimateEvolution(pUser, pFairy);

	// 재료 차감
	if (ACK_OK == ack || ACK_FAIRY_EVOLUTION_FAIL == ack)
	{
		pItem1->GetData().quantity -= itemQuantity1;
		pItem2->GetData().quantity -= itemQuantity2;

		if (0 >= pItem1->GetData().quantity)
		{
			pBagMisc->PopItem(itemSeq1);
			pItem1->DeleteDatabaseItemInfo(NLogic::Item::ItemStatus::EM_ITEM_STATUS_FAIRY_ULTIMATE_EVOLUTION);
		}
		else
		{
			pItem1->UpdateDatabaseItemInfo();
		}

		if (0 >= pItem2->GetData().quantity)
		{
			pBagMisc->PopItem(itemSeq2);
			pItem2->DeleteDatabaseItemInfo(NLogic::Item::ItemStatus::EM_ITEM_STATUS_FAIRY_ULTIMATE_EVOLUTION);
		}
		else
		{
			pItem2->UpdateDatabaseItemInfo();
		}

		if (ACK_OK == ack)
		{
			pFairy->UpdateDatabaseItemInfo();
		}
	}

	// 응답
	SendResponse(pUser, ack);
}

} /* NCommand */ } /* ProjectZ */
